{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: openai in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (0.28.0)\n",
      "Requirement already satisfied: requests>=2.20 in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from openai) (2.31.0)\n",
      "Requirement already satisfied: aiohttp in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from openai) (3.8.5)\n",
      "Requirement already satisfied: tqdm in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from openai) (4.66.1)\n",
      "Requirement already satisfied: idna<4,>=2.5 in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from requests>=2.20->openai) (3.4)\n",
      "Requirement already satisfied: urllib3<3,>=1.21.1 in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from requests>=2.20->openai) (2.0.4)\n",
      "Requirement already satisfied: charset-normalizer<4,>=2 in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from requests>=2.20->openai) (3.2.0)\n",
      "Requirement already satisfied: certifi>=2017.4.17 in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from requests>=2.20->openai) (2023.7.22)\n",
      "Requirement already satisfied: attrs>=17.3.0 in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from aiohttp->openai) (23.1.0)\n",
      "Requirement already satisfied: yarl<2.0,>=1.0 in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from aiohttp->openai) (1.9.2)\n",
      "Requirement already satisfied: frozenlist>=1.1.1 in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from aiohttp->openai) (1.4.0)\n",
      "Requirement already satisfied: multidict<7.0,>=4.5 in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from aiohttp->openai) (6.0.4)\n",
      "Requirement already satisfied: aiosignal>=1.1.2 in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from aiohttp->openai) (1.3.1)\n",
      "Requirement already satisfied: async-timeout<5.0,>=4.0.0a3 in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from aiohttp->openai) (4.0.3)\n",
      "Requirement already satisfied: colorama in c:\\users\\blcke\\appdata\\local\\packages\\pythonsoftwarefoundation.python.3.10_qbz5n2kfra8p0\\localcache\\local-packages\\python310\\site-packages (from tqdm->openai) (0.4.6)\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "\n",
      "[notice] A new release of pip is available: 23.0.1 -> 23.3.1\n",
      "[notice] To update, run: C:\\Users\\blcke\\AppData\\Local\\Microsoft\\WindowsApps\\PythonSoftwareFoundation.Python.3.10_qbz5n2kfra8p0\\python.exe -m pip install --upgrade pip\n"
     ]
    }
   ],
   "source": [
    "!pip install openai"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import openai\n",
    "import os\n",
    "\n",
    "\n",
    "openai.api_key = os.getenv('OPENAI_API_KEY')\n",
    "openai.api_base = os.getenv('OPENAI_API_BASE')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 辅助函数\n",
    "def get_completion(prompt,model = 'gpt-3.5-turbo'):\n",
    "    messages = [{\n",
    "        'role':'user',\n",
    "        'content' : prompt\n",
    "    }]\n",
    "\n",
    "    response = openai.ChatCompletion.create(\n",
    "        model = model,\n",
    "        messages = messages,\n",
    "        user = \"llm_cource\",\n",
    "        # 是一个介于 0 ~ 1 之间的数，数值越大，代表生成的结果越不一致/或者稳定\n",
    "        temperature = 0,\n",
    "    )\n",
    "    print(response.choices[0].message['content'])\n",
    "    return response.choices[0].message['content']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 大模型能力\n",
    "* 文本概括\n",
    "* 信息提取\n",
    "* 问答\n",
    "* 文本分类\n",
    "* 对话\n",
    "* 转换\n",
    "* 推理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 首先是文本概括"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Transformer模型是自注意力深度学习模型，用于NLP和CV领域。\n"
     ]
    }
   ],
   "source": [
    "information = \"Transformer模型（直译为“变换器”）是一种采用自注意力机制的深度学习模型，这一机制可以按输入数据各部分重要性的不同而分配不同的权重。该模型主要用于自然语言处理（NLP）与计算机视觉（CV）领域。[1]与循环神经网络（RNN）一样，Transformer模型旨在处理自然语言等顺序输入数据，可应用于翻译、文本摘要等任务。而与RNN不同的是，Transformer模型能够一次性处理所有输入数据。注意力机制可以为输入序列中的任意位置提供上下文。如果输入数据是自然语言，则Transformer不必像RNN一样一次只处理一个单词，这种架构允许更多的并行计算，并以此减少训练时间。[2]Transformer模型于2017年由谷歌大脑的一个团队推出[2]，现已逐步取代长短期记忆（LSTM）等RNN模型成为了NLP问题的首选模型。[3]并行化优势允许其在更大的数据集上进行训练。这也促成了BERT、GPT等预训练模型的发展。这些系统使用了维基百科、Common Crawl等大型语料库进行训练，并可以针对特定任务进行微调。[4][5]\"\n",
    "prompt = f\"\"\"\n",
    "用一句话概括下面的文本信息,不超过20个字：\n",
    "{information}\n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 信息提取"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Transformer模型于2017年由谷歌大脑的一个团队推出。\n"
     ]
    }
   ],
   "source": [
    "information = \"Transformer模型（直译为“变换器”）是一种采用自注意力机制的深度学习模型，这一机制可以按输入数据各部分重要性的不同而分配不同的权重。该模型主要用于自然语言处理（NLP）与计算机视觉（CV）领域。[1]与循环神经网络（RNN）一样，Transformer模型旨在处理自然语言等顺序输入数据，可应用于翻译、文本摘要等任务。而与RNN不同的是，Transformer模型能够一次性处理所有输入数据。注意力机制可以为输入序列中的任意位置提供上下文。如果输入数据是自然语言，则Transformer不必像RNN一样一次只处理一个单词，这种架构允许更多的并行计算，并以此减少训练时间。[2]Transformer模型于2017年由谷歌大脑的一个团队推出[2]，现已逐步取代长短期记忆（LSTM）等RNN模型成为了NLP问题的首选模型。[3]并行化优势允许其在更大的数据集上进行训练。这也促成了BERT、GPT等预训练模型的发展。这些系统使用了维基百科、Common Crawl等大型语料库进行训练，并可以针对特定任务进行微调。[4][5]\"\n",
    "prompt = f\"\"\"\n",
    "Transformer是哪一年提出的：\n",
    "{information}\n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 问答，基于特定的/给定的知识进行问答"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "不确定答案。\n"
     ]
    }
   ],
   "source": [
    "information = \"Transformer模型（直译为“变换器”）是一种采用自注意力机制的深度学习模型，这一机制可以按输入数据各部分重要性的不同而分配不同的权重。该模型主要用于自然语言处理（NLP）与计算机视觉（CV）领域。[1]与循环神经网络（RNN）一样，Transformer模型旨在处理自然语言等顺序输入数据，可应用于翻译、文本摘要等任务。而与RNN不同的是，Transformer模型能够一次性处理所有输入数据。注意力机制可以为输入序列中的任意位置提供上下文。如果输入数据是自然语言，则Transformer不必像RNN一样一次只处理一个单词，这种架构允许更多的并行计算，并以此减少训练时间。[2]Transformer模型于2017年由谷歌大脑的一个团队推出[2]，现已逐步取代长短期记忆（LSTM）等RNN模型成为了NLP问题的首选模型。[3]并行化优势允许其在更大的数据集上进行训练。这也促成了BERT、GPT等预训练模型的发展。这些系统使用了维基百科、Common Crawl等大型语料库进行训练，并可以针对特定任务进行微调。[4][5]\"\n",
    "prompt = f\"\"\"\n",
    "基于以下信息进行问答，如果不知道，请回答”不确定答案“。\n",
    "```\n",
    "{information}\n",
    "```\n",
    "问：通易千问是基于Transformer架构吗？\n",
    "答：\n",
    "\n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 文本分类\n",
    "文本分类用途广泛，比如情感，评论等数据分析工作；比如，判断一句话是消极，积极还是中性的；分析某个评论是好评还是差评等等；"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "积极的。\n"
     ]
    }
   ],
   "source": [
    "information = \"这件衣服有色差，不过还是不错的，喜欢\"\n",
    "prompt = f\"\"\"\n",
    "下面的评论是积极的，消极的，还是中性的？\n",
    "```\n",
    "{information}\n",
    "```\n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 对话\n",
    "大多数聊天，客服类应用场景"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你好，欢迎来到我们的外卖服务。有什么可以帮到您的吗？\n"
     ]
    }
   ],
   "source": [
    "prompt = f\"\"\"\n",
    "以下你是一个餐厅的外卖客服人员，你需要以‘小猪’著称，并且耐心回答用户的问题。\n",
    "用户: 你好。\n",
    "客服:\n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 转换\n",
    "比较典型的场景就是翻译；当然，对于我们开发人员来说，还可以在代码转换，比如python-》Java"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "英语：Chinese is the most interesting language in the world.\n",
      "法语：Le chinois est la langue la plus intéressante du monde.\n"
     ]
    }
   ],
   "source": [
    "prompt = f\"\"\"\n",
    "请将下面的句子转换成英语和法语：\n",
    "```\n",
    "汉语是世界上最有趣的语言。\n",
    "```\n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "```java\n",
      "import java.io.BufferedReader;\n",
      "import java.io.InputStreamReader;\n",
      "import java.net.HttpURLConnection;\n",
      "import java.net.URL;\n",
      "\n",
      "public class Main {\n",
      "    public static void main(String[] args) {\n",
      "        try {\n",
      "            URL url = new URL(\"https://api.openai.com/v1/chat/completions\");\n",
      "            HttpURLConnection connection = (HttpURLConnection) url.openConnection();\n",
      "            connection.setRequestMethod(\"POST\");\n",
      "            connection.setRequestProperty(\"Content-Type\", \"application/json\");\n",
      "            connection.setRequestProperty(\"Authorization\", \"Bearer $OPENAI_API_KEY\");\n",
      "            connection.setDoOutput(true);\n",
      "\n",
      "            String jsonInputString = \"{\\\"model\\\": \\\"gpt-3.5-turbo\\\",\\\"messages\\\": [{\\\"role\\\": \\\"user\\\", \\\"content\\\": \\\"Say this is a test!\\\"}],\\\"temperature\\\": 0.7}\";\n",
      "\n",
      "            try (OutputStream os = connection.getOutputStream()) {\n",
      "                byte[] input = jsonInputString.getBytes(\"utf-8\");\n",
      "                os.write(input, 0, input.length);\n",
      "            }\n",
      "\n",
      "            try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), \"utf-8\"))) {\n",
      "                StringBuilder response = new StringBuilder();\n",
      "                String responseLine = null;\n",
      "                while ((responseLine = br.readLine()) != null) {\n",
      "                    response.append(responseLine.trim());\n",
      "                }\n",
      "                System.out.println(response.toString());\n",
      "            }\n",
      "\n",
      "            connection.disconnect();\n",
      "        } catch (Exception e) {\n",
      "            e.printStackTrace();\n",
      "        }\n",
      "    }\n",
      "}\n",
      "```\n"
     ]
    }
   ],
   "source": [
    "code = 'curl https://api.openai.com/v1/chat/completions -H \"Content-Type: application/json\" -H \"Authorization: Bearer $OPENAI_API_KEY\" d {\"model\": \"gpt-3.5-turbo\",\"messages\": [{\"role\": \"user\", \"content\": \"Say this is a test!\"}],\"temperature\": 0.7}'\n",
    "prompt = f\"\"\"\n",
    "将下面的curl转换成Java代码：\n",
    "```\n",
    "{code}\n",
    "```\n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 推理\n",
    "比较典型的就是数学计算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4900\n"
     ]
    }
   ],
   "source": [
    "prompt = f\"\"\"\n",
    "70 * 70 = \n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 高级提示技巧"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# n-shot\n",
    "* zero-shot\n",
    "* one-shot/few-shot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "负面\n"
     ]
    }
   ],
   "source": [
    "# zero-shot\n",
    "prompt = f\"\"\"\n",
    "将文本分类为中性，负面或者正面。\n",
    "文本：我认为这篇教学没啥用\n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "这个产品的质量真的很差，太”的缴“了！\n"
     ]
    }
   ],
   "source": [
    "# one-shot\n",
    "prompt = f\"\"\"\n",
    "”牛逼“是指一个人或者一件事非常不错，一个使用”牛逼“的例子是：\n",
    "这课程质量真不错，挺”牛逼“的！\n",
    "”的缴“是指一个人或者事物非常差，一个使用”的缴“这个词的句子的例子是：\n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "// 消极\n",
      "这书太有趣了！// 积极\n",
      "这电影太无聊了！// 消极\n"
     ]
    }
   ],
   "source": [
    "# few-shot\n",
    "prompt = f\"\"\"\n",
    "这太棒了！// 积极\n",
    "这台糟糕了！// 消极\n",
    "哇！这视频真不赖！// 积极\n",
    "这声音真难听！//\n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 链式思考(Chain of thoughts) TOT\n",
    "就是通过one-shot/few-shot，让大模型学会通过推理的方式解决问题，然后再例子中给出推理的方法/步骤。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你还剩10个苹果。\n"
     ]
    }
   ],
   "source": [
    "# 反例\n",
    "prompt = f\"\"\"\n",
    "Q: 你有5个羽毛球，然后再买了2罐羽毛球，每罐羽毛球有3个，你现在共有多少个羽毛球？\n",
    "A：一个有11个\n",
    "Q：你有20个苹果，分给了5个小孩，每个小孩分了2个，后来又买了5个，你还剩多少个苹果？\n",
    "A：\n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "开始有20个苹果，分给5个小孩，每个小孩分了2个，就是5 * 2 = 10个苹果被分出去了。剩下的就是20 - 10 = 10个苹果。\n",
      "后来又买了5个苹果，所以现在共有10 + 5 = 15个苹果。\n"
     ]
    }
   ],
   "source": [
    "# 反例\n",
    "prompt = f\"\"\"\n",
    "Q: 你有5个羽毛球，然后再买了2罐羽毛球，每罐羽毛球有3个，你现在共有多少个羽毛球？\n",
    "A：你开始又5个羽毛球，又买了2罐，每罐3个，就是2 * 3 = 6个，加上开始的5个，现在一个又 5 + 6 = 11 个。\n",
    "Q：你有20个苹果，分给了5个小孩，每个小孩分了2个，后来又买了5个，你还剩多少个苹果？\n",
    "A：\n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "有一种更简单的方式，zero-shot，比较hack，就是在提示词当中加上类似”让我们一步一步推导/计算“就可以。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1. 20个苹果分给了5个小孩，每个小孩分了2个，共分出了5*2=10个苹果。\n",
      "2. 剩下的苹果数量为20-10=10个。\n",
      "3. 后来又买了5个苹果，现在总共有10+5=15个苹果剩下。\n"
     ]
    }
   ],
   "source": [
    "# 反例\n",
    "prompt = f\"\"\"\n",
    "Q：你有20个苹果，分给了5个小孩，每个小孩分了2个，后来又买了5个，你还剩多少个苹果？让我们一步一步推导。\n",
    "A：\n",
    "\"\"\"\n",
    "response = get_completion(prompt)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这个提示技巧用在比较复杂的任务当中，用于提高任务的准确率。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 思维树 ToT (Tree of Thoughts) https://arxiv.org/abs/2305.10601\n",
    "对于复杂的任务，如递归/搜索，大模型可能无法做出准确的计算，但是可以用思维树的方式，将复杂任务拆分，让大模型处理每一小步中的任务，再通过dfs，bfs等搜索算法，完成任务。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.11"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
